#ifndef GPU_DEGEN_SPOKE_DART_H
#define GPU_DEGEN_SPOKE_DART_H

#include <cuda.h>
#include <curand_kernel.h>
#include "vectorGpu.h"
#include "dataType.h"
#include "gpuDart.h"

class GPUDegenSpokeDart : public GPUDart
{
public:
	GPUDegenSpokeDart();
	virtual ~GPUDegenSpokeDart();

	virtual bool init(unsigned int m, DATA_TYPE radius, unsigned int d);
	virtual void setupDarts();
	virtual void updateIntervals();
	virtual void updateIntervals2();
	virtual void pickPoint();
	virtual void addSamples();
	virtual bool terminationCheck();
	virtual void downloadSamples();
	virtual unsigned int getNumGeneratedSamples();

	unsigned int getNextFront() const { return h_numNextFront_; }
	unsigned int getNumFront() const { return h_numFront_; }

protected:
	GPUMDVector d_directions_;
	GPUMDVector d_computedSamples_;

	unsigned int* d_numSamples_;
	unsigned int* d_numFront_;
	unsigned int* d_failureCount_;
	unsigned int* d_nextFront_;

	unsigned int h_numFront_;
	unsigned int h_numNextFront_;
};

namespace GPUDegenSpokeDartCuda
{
	__global__ void initRandomStates(curandState* randStates, unsigned int* pNextFront, GPUDart::GPUMDVector samples, VectorGPU* pFirstSample);
	__global__ void setupGPUDarts(unsigned int* pNumFronts, GPUDart::GPUMDVector samples, curandState* randStates, GPUDart::GPUMDVector refPoints, GPUDart::GPUMDVector directions,
		GPUDart::GPUInterval* intervals);
	__global__ void pickPointKernel(unsigned int* pNumFronts, curandState* randStates, unsigned int *d_numSamples, GPUDart::GPUMDVector samples,
		GPUDart::GPUMDVector refPoints, GPUDart::GPUMDVector directions, GPUDart::GPUMDVector computedSamples);
	__global__ void addSamplesKernel(unsigned int* pNumFronts, GPUDart::GPUMDVector samples, 
		unsigned int *pNumSamples, unsigned int* pFailureCounts, GPUDart::GPUMDVector computedSamples,
		unsigned int* d_gridcells, unsigned int* d_numGridCellElements);
	__global__ void updateFront(unsigned int* pNumFronts, unsigned int *pNumSamples, unsigned int* pFailureCounts, unsigned int* pNextFront, unsigned int numBlocks);
};

#endif